#ifndef SPL06_01_H
#define SPL06_01_H

#include <stdint.h>
#include "sensor_goer_spl0601.h"
#define CONTINUOUS_PRESSURE     1
#define CONTINUOUS_TEMPERATURE  2
#define CONTINUOUS_P_AND_T      3
#define PRESSURE_SENSOR     0
#define TEMPERATURE_SENSOR  1
enum reg_meas_ctrl_mode {
    MEAS_CTRL_STOP = 0,
    MEAS_CTRL_PRESSURE_MEASUREMENT,
    MEAS_CTRL_TEMPERATURE_MEASUREMENT,
    MEAS_CTRL_NA1,
    MEAS_CTRL_NA2,
    MEAS_CTRL_CONTINUOUS_PRESSURE_MEASUREMENT,
    MEAS_CTRL_CONTINUOUS_TEMPERATURE_MEASUREMENT,
    MEAS_CTRL_CONTINUOUS_P_AND_T_MEASUREMENT,
};

/**pressure and temperature measurement rate */
enum spl06_measurement_rate {
    PT_MEASUREMENT_RATE_1 = 0,
    PT_MEASUREMENT_RATE_2,
    PT_MEASUREMENT_RATE_4,
    PT_MEASUREMENT_RATE_8,
    PT_MEASUREMENT_RATE_16,
    PT_MEASUREMENT_RATE_32,
    PT_MEASUREMENT_RATE_64,
    PT_MEASUREMENT_RATE_128,

};
/**pressure and temperature oversample rate */
enum spl06_oversample_rate {
    PT_OVERSAMPLE_RATE_1 = 0,
    PT_OVERSAMPLE_RATE_2,
    PT_OVERSAMPLE_RATE_4,
    PT_OVERSAMPLE_RATE_8,
    PT_OVERSAMPLE_RATE_16,
    PT_OVERSAMPLE_RATE_32,
    PT_OVERSAMPLE_RATE_64,
    PT_OVERSAMPLE_RATE_128
};

enum SPL0601_REG_INDEX {
    SPL0601_REG_PRS_B2 = 0x00, // Pressure MSB
    SPL0601_REG_PRS_B1, // Pressure LSB
    SPL0601_REG_PRS_B0, // Pressure XLSB

    SPL0601_REG_TMP_B2, // Temperature LSB
    SPL0601_REG_TMP_B1, // Temperature MSB
    SPL0601_REG_TMP_B0, // Temperature XLSB

    SPL0601_REG_PRS_CFG, // Temperature Configuration
    SPL0601_REG_TMP_CFG, // Temperature Configuration
    SPL0601_REG_MEAS_CFG, // Temperature Threshold
    SPL0601_REG_CFG_REG, // Temperature Threshold
    SPL0601_REG_INT_STS, // Temperature Threshold
    SPL0601_REG_FIFO_STS, // Temperature Threshold
    SPL0601_REG_RESET, // Temperature Threshold
    SPL0601_REG_ID, // Temperature Threshold
    SPL0601_REG_COEF = 0x10, // Temperature Threshold
};
enum spl06_working_mode{
    SPL06_MODE_WEATHER_STATION=0,//(low power, background mode. 5 Pa precision. 1 pr sec. 6uA)
    SPL06_MODE_INDOOR_NAVIGATION,//(standard precision, background mode. 10 cm percision. 2 pr sec. 30 uA)
    SPL06_MODE_SPORTS,//(high precision, high rate,background mode. 5 cm percision 4 pr sec. 200 uA)
};
struct spl06_register_map {
    uint8_t PRS_B2;
    uint8_t PRS_B1;
    uint8_t PRS_B0;
    uint8_t TMP_B2;
    uint8_t TMP_B1;
    uint8_t TMP_B0;
    union
    {

        uint8_t PRS_CFG;
        struct {
            uint8_t PM_PRC : 4;
            uint8_t PM_RATE : 3;
        }__packed prs_cfg_bit;
    };
    union
    {

        uint8_t TMP_CFG;
        struct {
            uint8_t PM_PRC : 3;//Temperature oversampling (precision)
            uint8_t res1 : 1;
            uint8_t PM_RATE : 3;//Temperature measurement rate:
            /**
             * Temperature measurement
             * 0 - Internal sensor (in ASIC)
             * 1 - External sensor (in pressure sensor MEMS element)
             * Note: Please use the external sensor setting.
             */
            uint8_t TMP_EX : 1;
        }__packed tmp_cfg_bit;
    };
    union
    {

        uint8_t MEAS_CFG;
        struct {
            uint8_t MEAS_CTRL : 3;
            uint8_t res1 : 1;
            uint8_t PRS_RDY : 1;
            uint8_t TMP_RDY : 1;
            uint8_t SENSOR_RDY : 1;
            /**Coefficients will be read to the Coefficients Registers 
             * after start- up:
             * 0 - Coefficients are not available yet.
             * 1 - Coefficients are available. */
            uint8_t COEF_RDY : 1;
        }__packed meas_cfg_bit;
    };
    union {
        uint8_t CFG_REG;
        struct {
            uint8_t SPI_MODE : 1;/**Set SPI mode:0-4-wire interface.1-3-wire interface. */
            uint8_t FIFO_EN : 1;/**Enable the FIFO:0 - Disable.1 - Enable. */
            uint8_t P_SHIFT : 1;/**Must be set to '1' when the oversampling rate is >8 times. */
            uint8_t T_SHIFT : 1;/**Must be set to '1' when the oversampling rate is >8 times. */
            uint8_t INT_TMP : 1;
            uint8_t INT_PRS : 1;
            uint8_t INT_FIFO : 1;
            uint8_t INT_HL : 1;
        }__packed cfg_reg_bit;
    };
    union {
        uint8_t INT_STS;
        struct {
            uint8_t INT_PRS : 1;
            uint8_t INT_TMP : 1;
            uint8_t INT_FIFO_FULL : 1;
            uint8_t res : 5;
        }__packed int_sts_bit;
    };
    union {
        uint8_t FIFO_STS;
        struct {
            uint8_t FIFO_EMPTY : 1;
            uint8_t FIFO_FULL : 1;
            uint8_t res : 6;
        }__packed fifo_sts_bit;
    };
    union {
        uint8_t RESET;
        struct {
            uint8_t SOFT_RST : 4;
            uint8_t res : 3;
            uint8_t FIFO_FLUSH : 1;
        }__packed reset_bit;
    };
    union {
        uint8_t ID;
        struct {
            uint8_t REV_ID : 4;
            uint8_t PRO_ID : 4;
        }__packed id_bit;
    };

};
union spl06_coef {
    struct {
        int32_t c30 : 16;//20-21
        int32_t c21 : 16;//1e-1f
        int32_t c20 : 16;//1c-1d
        int32_t c11 : 16;//1a-1b
        int32_t c01 : 16;//18-19
        int32_t c10 : 20;//15-17
        int32_t c00 : 20;//13-15
        int32_t c1 : 12;//11-12
        int32_t c0 : 12;//10-11
        int32_t res : 16;
    }__packed;
    uint8_t coef[20];
};
struct spl0601_calib_param_t {
    int16_t c0;
    int16_t c1;
    int32_t c00;
    int32_t c10;
    int16_t c01;
    int16_t c11;
    int16_t c20;
    int16_t c21;
    int16_t c30;
};
struct spl06_odr{
    enum spl06_measurement_rate odr;
    enum spl06_oversample_rate prc;
};
typedef struct spl0601_t {
    union spl06_coef calib_param;/**<calibration data*/
    uint8_t chip_id; /**<chip id*/
    int32_t i32rawPressure;
    int32_t i32rawTemperature;
    int32_t i32kP;
    int32_t i32kT;
#if defined(SPL0601_BUS_MODE_SPI)
    struct rt_spi_device* bus;
#elif defined(SPL0601_BUS_MODE_I2C)
    struct rt_i2c_bus_device* bus;
#endif

} spl0601_t;


int spl0601_init(spl0601_t* hdev, const char* busname);
void spl0601_rateset(spl0601_t* hdev, uint8_t iSensor, uint8_t u8OverSmpl, uint8_t u8SmplRate);
void spl0601_start_temperature(spl0601_t* hdev);
void spl0601_start_pressure(spl0601_t* hdev);
void spl0601_start_continuous(spl0601_t* hdev, uint8_t mode);
void spl0601_get_raw_temp(spl0601_t* hdev);
void spl0601_get_raw_pressure(spl0601_t* hdev);
float spl0601_get_temperature(spl0601_t* hdev);
float spl0601_get_pressure(spl0601_t* hdev);


void spl06_temperature_rate_set(spl0601_t* hdev, enum spl06_measurement_rate pm, enum spl06_oversample_rate prc);
void spl06_pressure_rate_set(spl0601_t* hdev, enum spl06_measurement_rate pm, enum spl06_oversample_rate prc);

#endif

